Find the window you wanted by using EnumWindows

Introduction

During the development of windows application, you can operate other windows by enumerating windows with EnumWindows.


Details

The original link is 使用 EnumWindows 找到满足你要求的窗口 - walterlv. But this blog was written in Chinese, so I translate its content to English. Waterlv is an MVP(Microsoft Most Valuable Professional), and he is good at .NET Core\WPF\.NET. Here is his Blog.

EnumWindows

You can get more details about EnumWindows from the Microsoft website.

Before you use EnumWindows with C# , you have to write a platform to call the P/Invoke method.

Like this:

1
2
[DllImport("user32.dll")]
public static extern int EnumWindows(WndEnumProc lpEnumFunc, int lParam);

Enumerate all top-level windows

This is the official document for this API description,

Enumerates all top-level windows on the screen by passing the handle to each window, in turn, to an application-defined callback function.

But not all the enumerated windows are top-level windows, some windows are not top-level windows.For more details,visit EnumWindows remarks.

So,we can get all windows by running these codes followed,

1
2
3
4
5
6
7
8
9
10
11
12
13
public static IReadOnlyList<int> EnumWindows()
{
var windowList = new List<int>();
EnumWindows(OnWindowEnum, 0);
return windowList;

bool OnWindowEnum(int hwnd, int lparam)
{
// you can add some conditions here.
windowList.Add(hwnd);
return true;
}
}

Enumerate windows with a specific title or class name

You should add some Win32 API to filter windows. These APIs are the methods we plan to use.

1
2
3
4
5
6
7
// get class name of specific window
[DllImport("user32.dll")]
private static extern int GetClassName(int hWnd, StringBuilder lpString, int nMaxCount);

// get title of specific window
[DllImport("user32")]
public static extern int GetWindowText(int hwnd, StringBuilder lptrString, int nMaxCount);

We can enumerate windows with specific class name by running the code,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static IReadOnlyList<int> FindWindowByClassName(string className)
{
var windowList = new List<int>();
EnumWindows(OnWindowEnum, 0);
return windowList;

bool OnWindowEnum(int hwnd, int lparam)
{
var lpString = new StringBuilder(512);
GetClassName(hwnd, lpString, lpString.Capacity);
if (lpString.ToString().Equals(className, StringComparison.InvariantCultureIgnoreCase))
{
windowList.Add(hwnd);
}

return true;
}
}

Also, you can change the method from GetClassName to GetWindowText to enumerate windows by specific title.

1
2
var lpString = new StringBuilder(512);
GetWindowText(hwnd,lpString,lpString.Capacity);

References